package com.zengqingfa.producerconsumer;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @fileName: ConsumerProducerWithBlockingWaitNotify
 * @author: zengqingfa
 * @date: 2022/12/14 16:34
 * @description:
 */
public class ConsumerProducerWithBlockingWaitNotify {


    public static void main(String[] args) {
        ConsumerProducerWithBlockingWaitNotify waitNotify = new ConsumerProducerWithBlockingWaitNotify();
        Storage storage = waitNotify.new Storage();
        Producer producer = waitNotify.new Producer(storage);
        Consumer consumer = waitNotify.new Consumer(storage);
        producer.start();
        consumer.start();
    }

    class Consumer extends Thread {

        private Storage storage;

        public Consumer(Storage storage) {
            this.storage = storage;
        }

        @Override
        public void run() {
            try {
                for (int i = 0; i < 100; i++) {
                    System.out.println("取出队列数据：" + storage.take() + ",仓库还有：" + storage.getList().size());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class Producer extends Thread {

        private Storage storage;

        public Producer(Storage storage) {
            this.storage = storage;
        }

        @Override
        public void run() {
            try {
                for (int i = 0; i < 100; i++) {
                    System.out.println("生产者放入队列：" + i);
                    storage.put(i);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class Storage {
        private LinkedList<Integer> list = null;
        private int maxSize = 0;

        public Storage() {
            this.list = new LinkedList<>();
            this.maxSize = 10;
        }

        public LinkedList<Integer> getList() {
            return list;
        }

        /**
         * 放入数据
         *
         * @param num
         * @throws InterruptedException
         */
        public synchronized void put(int num) throws InterruptedException {
            while (list.size() == maxSize) {
                wait();
            }
            list.add(num);
            notify();
        }

        /**
         * 取出数据
         *
         * @throws InterruptedException
         */
        public synchronized int take() throws InterruptedException {
            while (list.isEmpty()) {
                wait();
            }
            Integer poll = list.poll();
            notify();
            return poll;
        }
    }
}
